import os
import json
import logging
import copy
from typing import Dict, Any, List, Optional
import time

class SettingsManager:
    """设置管理器，负责处理个性化设置的存储、读取和应用"""
    
    def __init__(self, settings_file: str = "config.json"):
        self.settings_file = os.path.join(os.path.dirname(os.path.abspath(__file__)), settings_file)
        self._default_settings = {
            "general": {
                "theme": "light",  # light, dark, system
                "language": "zh-CN",
                "auto_start": False,
                "show_notifications": True,
                "minimize_to_tray": True
            },
            "voice": {
                "enabled": True,
                "volume": 1.0,
                "rate": 1.0,
                "pitch": 1.0,
                "voice_id": "",
                "emotion_level": 0.5,  # 0.0-1.0, 控制情感表达强度
                "silence_duration": 0.2  # 语音间隔时间
            },
            "commands": {
                "custom_commands": {},
                "command_aliases": {},
                "disabled_commands": []
            },
            "context": {
                "max_history": 10,
                "context_timeout": 300,  # 5分钟
                "auto_clear_context": True
            },
            "error_handling": {
                "auto_retry": True,
                "max_retries": 2,
                "retry_delay": 1.0,
                "show_suggestions": True
            },
            "shortcuts": {
                "global_hotkey": "ctrl+alt+space",
                "show_help": "F1",
                "toggle_voice": "ctrl+v"
            },
            "appearance": {
                "font_size": 12,
                "font_family": "Microsoft YaHei",
                "window_always_on_top": False,
                "show_tray_icon": True
            },
            "models": {
                "default_model": "auto",
                "cache_enabled": True,
                "cache_size": 100,  # 缓存条目数
                "auto_switch_model": True
            }
        }
        
        self._settings = copy.deepcopy(self._default_settings)
        self._context_history: Dict[str, List[Dict[str, Any]]] = {}
        self._context_timestamps: Dict[str, float] = {}
        self._load_settings()
        
    def _load_settings(self) -> None:
        """从文件加载设置"""
        try:
            if os.path.exists(self.settings_file):
                with open(self.settings_file, 'r', encoding='utf-8') as f:
                    loaded_settings = json.load(f)
                    # 递归合并设置，保留未指定的默认值
                    self._merge_settings(self._settings, loaded_settings)
                logging.info(f"设置从 {self.settings_file} 加载成功")
            else:
                logging.info(f"设置文件不存在，使用默认设置")
                self.save_settings()  # 创建默认配置文件
        except Exception as e:
            logging.error(f"加载设置失败: {str(e)}")
            # 使用默认设置
            self._settings = copy.deepcopy(self._default_settings)
    
    def _merge_settings(self, target: Dict[str, Any], source: Dict[str, Any]) -> None:
        """递归合并设置字典"""
        for key, value in source.items():
            if key in target and isinstance(target[key], dict) and isinstance(value, dict):
                self._merge_settings(target[key], value)
            else:
                target[key] = value
    
    def save_settings(self) -> bool:
        """保存设置到文件"""
        try:
            # 确保目录存在
            os.makedirs(os.path.dirname(self.settings_file), exist_ok=True)
            
            with open(self.settings_file, 'w', encoding='utf-8') as f:
                json.dump(self._settings, f, ensure_ascii=False, indent=2)
            logging.info(f"设置已保存到 {self.settings_file}")
            return True
        except Exception as e:
            logging.error(f"保存设置失败: {str(e)}")
            return False
    
    def get_setting(self, key_path: str, default: Any = None) -> Any:
        """获取指定路径的设置值"""
        keys = key_path.split('.')
        value = self._settings
        
        try:
            for key in keys:
                value = value[key]
            return value
        except (KeyError, TypeError):
            return default
    
    def set_setting(self, key_path: str, value: Any) -> bool:
        """设置指定路径的设置值"""
        keys = key_path.split('.')
        settings = self._settings
        
        try:
            # 导航到目标键的父级
            for key in keys[:-1]:
                if key not in settings or not isinstance(settings[key], dict):
                    settings[key] = {}
                settings = settings[key]
            
            # 设置最终值
            settings[keys[-1]] = value
            return True
        except Exception as e:
            logging.error(f"设置值失败: {str(e)}")
            return False
    
    def reset_settings(self) -> bool:
        """重置所有设置到默认值"""
        try:
            self._settings = copy.deepcopy(self._default_settings)
            return self.save_settings()
        except Exception as e:
            logging.error(f"重置设置失败: {str(e)}")
            return False
    
    def get_all_settings(self) -> Dict[str, Any]:
        """获取所有设置"""
        return copy.deepcopy(self._settings)
    
    # 上下文管理相关方法
    def add_to_context(self, user_id: str, message: Dict[str, Any]) -> None:
        """添加消息到上下文历史"""
        if user_id not in self._context_history:
            self._context_history[user_id] = []
        
        # 添加时间戳
        message['timestamp'] = time.time()
        self._context_history[user_id].append(message)
        self._context_timestamps[user_id] = time.time()
        
        # 限制历史记录长度
        max_history = self.get_setting('context.max_history', 10)
        if len(self._context_history[user_id]) > max_history:
            self._context_history[user_id] = self._context_history[user_id][-max_history:]
    
    def get_context(self, user_id: str) -> List[Dict[str, Any]]:
        """获取用户上下文历史"""
        # 检查上下文是否过期
        self._clean_expired_context(user_id)
        
        if user_id not in self._context_history:
            return []
        
        return copy.deepcopy(self._context_history[user_id])
    
    def clear_context(self, user_id: str) -> None:
        """清除用户上下文历史"""
        if user_id in self._context_history:
            del self._context_history[user_id]
        if user_id in self._context_timestamps:
            del self._context_timestamps[user_id]
    
    def _clean_expired_context(self, user_id: str) -> None:
        """清理过期的上下文"""
        if not self.get_setting('context.auto_clear_context', True):
            return
        
        if user_id in self._context_timestamps:
            timeout = self.get_setting('context.context_timeout', 300)
            if time.time() - self._context_timestamps[user_id] > timeout:
                self.clear_context(user_id)
    
    # 命令别名和自定义命令处理
    def resolve_command_alias(self, command: str) -> str:
        """解析命令别名"""
        aliases = self.get_setting('commands.command_aliases', {})
        return aliases.get(command, command)
    
    def is_command_disabled(self, command: str) -> bool:
        """检查命令是否被禁用"""
        disabled = self.get_setting('commands.disabled_commands', [])
        return command in disabled
    
    def get_custom_command(self, command_name: str) -> Optional[Dict[str, Any]]:
        """获取自定义命令配置"""
        custom_commands = self.get_setting('commands.custom_commands', {})
        return custom_commands.get(command_name)
    
    # 错误处理相关方法
    def get_error_handling_settings(self) -> Dict[str, Any]:
        """获取错误处理设置"""
        return self.get_setting('error_handling', {})
    
    def generate_retry_suggestion(self, error: str, command: str) -> str:
        """根据错误生成重试建议"""
        # 常见错误模式和建议
        suggestions = {
            "未找到文件": f"请检查文件路径是否正确，命令: {command}",
            "权限被拒绝": f"请以管理员权限运行程序，命令: {command}",
            "参数错误": f"请检查命令参数格式，命令: {command}",
            "应用未找到": f"请确保目标应用已安装，命令: {command}"
        }
        
        # 查找匹配的错误模式
        for pattern, suggestion in suggestions.items():
            if pattern in error:
                return suggestion
        
        # 通用建议
        return f"命令执行失败: {error}\n建议: 检查命令参数并重试，或使用不同的命令格式"
    
    # 语音设置相关方法
    def get_voice_settings(self) -> Dict[str, Any]:
        """获取语音设置"""
        return self.get_setting('voice', {})
    
    def get_emotional_params(self, emotion_type: str = "neutral") -> Dict[str, float]:
        """获取带有情感参数的语音设置"""
        base_settings = self.get_voice_settings()
        emotion_level = base_settings.get('emotion_level', 0.5)
        
        # 不同情感类型的参数调整
        emotion_adjustments = {
            "happy": {"pitch": 1.1, "rate": 1.1, "volume": 1.1},
            "sad": {"pitch": 0.9, "rate": 0.9, "volume": 0.9},
            "excited": {"pitch": 1.2, "rate": 1.3, "volume": 1.2},
            "calm": {"pitch": 1.0, "rate": 0.9, "volume": 0.9},
            "neutral": {"pitch": 1.0, "rate": 1.0, "volume": 1.0}
        }
        
        adjustments = emotion_adjustments.get(emotion_type, emotion_adjustments["neutral"])
        
        # 应用情感调整
        result = {
            "rate": base_settings.get('rate', 1.0) * (1 + (adjustments["rate"] - 1) * emotion_level),
            "pitch": base_settings.get('pitch', 1.0) * (1 + (adjustments["pitch"] - 1) * emotion_level),
            "volume": base_settings.get('volume', 1.0) * (1 + (adjustments["volume"] - 1) * emotion_level)
        }
        
        # 确保值在有效范围内
        for key, value in result.items():
            result[key] = max(0.1, min(3.0, value))
        
        return result

# 创建全局设置管理器实例
settings_manager = SettingsManager()

# 导出主要功能
def get_setting(key_path: str, default: Any = None) -> Any:
    """便捷函数：获取设置"""
    return settings_manager.get_setting(key_path, default)

def set_setting(key_path: str, value: Any) -> bool:
    """便捷函数：设置值并保存"""
    result = settings_manager.set_setting(key_path, value)
    if result:
        settings_manager.save_settings()
    return result

def get_context(user_id: str = "default") -> List[Dict[str, Any]]:
    """便捷函数：获取上下文"""
    return settings_manager.get_context(user_id)

def add_to_context(message: Dict[str, Any], user_id: str = "default") -> None:
    """便捷函数：添加到上下文"""
    settings_manager.add_to_context(user_id, message)

def clear_context(user_id: str = "default") -> None:
    """便捷函数：清除上下文"""
    settings_manager.clear_context(user_id)

def get_error_suggestion(error: str, command: str) -> str:
    """便捷函数：获取错误建议"""
    return settings_manager.generate_retry_suggestion(error, command)

def get_voice_params(emotion: str = "neutral") -> Dict[str, float]:
    """便捷函数：获取带情感的语音参数"""
    return settings_manager.get_emotional_params(emotion)

# 日志配置
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)